package com.cpd.blog.manager.manager.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cpd.blog.common.constant.RedisKey;
import com.cpd.blog.common.constant.StatusCode;
import com.cpd.blog.common.utils.*;
import com.cpd.blog.dto.Result;
import com.cpd.blog.entity.Article;
import com.cpd.blog.entity.User;
import com.cpd.blog.manager.manager.UserManager;
import com.cpd.blog.manager.mapper.ArticleMapper;
import com.cpd.blog.manager.mapper.UserMapper;
import lombok.RequiredArgsConstructor;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @Author: Copydown
 * @Date: 2022/05/07/13:29
 */
@Service
@RequiredArgsConstructor
public class UserManagerImpl implements UserManager {

    private final UserMapper userMapper;

    private final ArticleMapper articleMapper;

    private final RedisUtil redisUtil;

    @Override
    public User updateUserLogin(User user, String token) {

        LocalDateTime now = LocalDateTime.now();
        user.setLastLogin(now);

        String deleteToken = redisUtil.deleteHashWithCount(RedisKey.IS_LOGIN, user.getId());
        if (deleteToken != null && redisUtil.delete(RedisKey.TOKEN + deleteToken)) {
            LogUtil.log("loginMap、旧token 删除成功：{}", user.getId(), deleteToken);
        }
        //更新 loginMap
        redisUtil.setHash(RedisKey.IS_LOGIN, user.getId(), token);

        if (userMapper.updateById(user) <= 0) {
            return null;
        }
        return user;
    }

    @Override
    public Long calViewCountsById(Long id) {
        QueryWrapper<Article> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("author_id", id)
                .select("IFNULL(SUM(view_counts),0) view_counts");
        Article article = articleMapper.selectOne(queryWrapper);
        return article.getViewCounts();
    }

    @Override
    public Long countArticleById(Long id) {
        QueryWrapper<Article> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("author_id", id)
                .select("IFNULL(count(*),0) view_counts");
        Article article = articleMapper.selectOne(queryWrapper);
        return article.getViewCounts();
    }

    @Override
    public List<User> findUserListByNickName(String name) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getNickname, name);

        return userMapper.selectList(queryWrapper);
    }

    @Override
    public Boolean changeUserNickName(String name) {

        User user = userMapper.selectById(CurrentUser.getId());
        user.setNickname(name);
        user.setModifyTime(TimeUtil.getNowLocalDateTime());

        if (userMapper.updateById(user) == 1) {
            LogUtil.log(StatusCode.USER_CHANGE_NICKNAME_SUCCESS);
            return true;
        }
        LogUtil.log(StatusCode.USER_CHANGE_NICKNAME_FAILED);
        return false;
    }

    @Override
    public Result changePassword(String password) {
        User user = userMapper.selectById(CurrentUser.getId());
        String newPassword = DigestUtils.md5Hex(password + user.getSalt());

        if (CheckUtil.isEquals(user.getPassword(), newPassword)) {
            return Result.fail(StatusCode.USER_PASSWORD_SAME);
        }

        user.setPassword(DigestUtils.md5Hex(password + user.getSalt()));
        user.setModifyTime(TimeUtil.getNowLocalDateTime());

        if (userMapper.updateById(user) == 1) {
            LogUtil.log(StatusCode.USER_CHANGE_PASSWORD_SUCCESS);
            return Result.success();
        }
        LogUtil.log(StatusCode.USER_CHANGE_PASSWORD_FAILED);
        return Result.fail(StatusCode.USER_CHANGE_PASSWORD_FAILED);
    }
}
